package cn.wolfcode.service.impl;

import cn.wolfcode.common.exception.BusinessException;
import cn.wolfcode.common.web.CommonCodeMsg;
import cn.wolfcode.common.web.Result;
import cn.wolfcode.domain.Product;
import cn.wolfcode.domain.SeckillProduct;
import cn.wolfcode.domain.SeckillProductVo;
import cn.wolfcode.feign.ProductFeignApi;
import cn.wolfcode.mapper.SeckillProductMapper;
import cn.wolfcode.redis.SeckillRedisKey;
import cn.wolfcode.service.ISeckillProductService;
import cn.wolfcode.web.msg.SeckillCodeMsg;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;


@Slf4j
@Service
public class SeckillProductServiceImpl implements ISeckillProductService {
    @Autowired
    private SeckillProductMapper seckillProductMapper;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    @Autowired
    private ProductFeignApi productFeignApi;


    @Override
    public List<SeckillProductVo> selectByTime(Integer time) {
        List<SeckillProduct> seckillProducts = seckillProductMapper.queryCurrentlySeckillProduct(time);

        ArrayList<Long> productIdList = new ArrayList<>();
        for (SeckillProduct seckillProduct : seckillProducts) {
            productIdList.add(seckillProduct.getProductId());
        }
        //通过Feign远程调用product-server去查询商品信息
        Result<List<Product>> result = productFeignApi.selectByIds(productIdList);
        List<Product> productList = result.getData();
        if(result==null || result.hasError()) {
            throw new BusinessException(CommonCodeMsg.ILLEGAL_OPERATION);
        }
        Map<Long,Product> temp = new HashMap<>();
        for (Product product : productList) {
            temp.put(product.getId(),product);
        }

        List<SeckillProductVo> vos = new ArrayList<>();
        for (SeckillProduct seckillProduct : seckillProducts) {
            SeckillProductVo seckillProductVo = new SeckillProductVo();
            //将限时秒杀数据放到vo对象中
            Product product = temp.get(seckillProduct.getProductId());
            BeanUtils.copyProperties(product,seckillProductVo);
            //将商品信息放到vo对象中
            BeanUtils.copyProperties(seckillProduct,seckillProductVo);

            vos.add(seckillProductVo);
        }

        return vos;
    }

    @Override
    public List<SeckillProductVo> queryByTime(Integer time) {
        List<Object> values = redisTemplate.opsForHash().values(SeckillRedisKey.SECKILL_PRODUCT_LIST.getRealKey(time + ""));
        if(values.size() == 0) {
            return Collections.emptyList();
        }
        List<SeckillProductVo> list = new ArrayList<>();
        for (Object value : values) {
            list.add(JSON.parseObject(value.toString(),SeckillProductVo.class));
        }

        return list;
    }

    @Override
    public SeckillProductVo find(Integer time, Long seckillId) {
        Object o = redisTemplate.opsForHash().get(SeckillRedisKey.SECKILL_PRODUCT_LIST.getRealKey(time + ""), seckillId+"");

        if(o==null) {
            log.info("商品详情为空");
            return null;
        }
        SeckillProductVo seckillProductVo = JSON.parseObject(o.toString(), SeckillProductVo.class);

        return seckillProductVo;
    }

    @Override
    public void decrStockCount(SeckillProductVo seckillProductVo) {
        int i = seckillProductMapper.decrStock(seckillProductVo.getId());
        if(i>0) {
            //扣除redis库存
            String realKey = SeckillRedisKey.SECKILL_PRODUCT_LIST.getRealKey(seckillProductVo.getTime() + "");
            redisTemplate.opsForHash().put(realKey,seckillProductVo.getId()+"",JSON.toJSONString(seckillProductVo));
        } else {
            throw new BusinessException(SeckillCodeMsg.SECKILL_STOCK_OVER);
        }
    }
}
